import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "../utils/token-utils";
import { ElMessage } from "element-plus";
import { staticRoutes, allAsyncRoutes, anyRoute } from "@/router/routes";
import {
  requestLogin,
  requestLogout,
  requestUserInfo,
  type reqLoginParamsType,
  type reqUserInfoReturnType
} from "@/api/userInfo";
import type { RouteRecordRaw } from "vue-router";
import router from "@/router";
import cloneDeep from "lodash/cloneDeep";
import { logicNot } from "@vueuse/core";

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
/**@filterAsyncRoutes 过滤掉没有权限的路由的函数*/
function filterAsyncRoutes(allAsyncRoutes: RouteRecordRaw[], routeNames: string[]) {
  return allAsyncRoutes.filter(item => {
    if (routeNames.includes(item.name as string)) {
      if (item.children && item.children.length) {
       item.children = filterAsyncRoutes(item.children, routeNames);
      }
      return true;
    }
  });
}

/**@addRoutes 添加多个路由到路由器的函数 */
function addRoutes(allAsyncRoutes: RouteRecordRaw[]) {
  allAsyncRoutes.forEach(item => {
    router.addRoute(item);
  });
}

/**@resetRouters 清除路由器中的路由表*/
function resetRouters(staticRoutes:RouteRecordRaw[]) {
  //getRoutes函数返回完整的路由表，遍历路由表通过name删除路由
  router.getRoutes().forEach(item => {
    router.removeRoute(item.name as string);
  });
  //删完后在将静态路由设置
  addRoutes(staticRoutes);
}


// 用户信息包括权限数据
export interface UserInfoState {
  token: string;
  userInfo: reqUserInfoReturnType;
  menuRoutes: RouteRecordRaw[]; // 用于生成导航菜单的路由列表
}

export const useUserInfoStore = defineStore("userInfo", {
  state: (): UserInfoState => ({
    token: (getToken() as string) || "",
    userInfo: {
      routes: [],
      buttons: [],
      roles: [],
      name: "",
      avatar: ""
    },
    //将静态路由表保存起来，侧边栏是通过这个路由表遍历生成侧边栏的元素的
    menuRoutes: staticRoutes
  }),

  actions: {
    //登陆的方法
    async login(loginParam: reqLoginParamsType) {
      try {
        //发送登陆请求
        const result = await requestLogin(loginParam);
        //拿到结果token设置在state中
        this.token = result.token;
        //设置自动登陆（持久化保存token）
        setToken(this.token);
      } catch (e) {
        //如果调用该方法，请求的时候出问题则返回一个失败的promise实例
        Promise.reject(e);
      }
    },
    //获取用户信息
    async getInfo() {
      try {
        //发送用户信息请求
        const result = await requestUserInfo();
        //把数据交给state
        this.userInfo = result;
        //将数据拿去生成路由表
        const userAsyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), result.routes);
        //将路由配置到路由器中
        addRoutes(userAsyncRoutes);
        //将数据给到静态路由表
        this.menuRoutes = staticRoutes.concat(userAsyncRoutes, anyRoute);
      } catch (e) {
        //获取信息失败抛出异常
        return Promise.reject(e);
      }
    },

    async getLogout() {
      try {
        //退出登陆的请求
        await requestLogout(); //退出登陆的请求
        this.reset();
        //清除数据
        this.reset();
        //退出登陆清除路由表信息
        resetRouters(staticRoutes);
      } catch (e) {
        return Promise.reject(e);
      }
    },
    reset() {
      // 删除local中保存的token
      removeToken();
      // 提交重置用户信息的mutation
      this.token = "";
      //恢复到state初始的数据
      this.userInfo = {
        routes: [],
        buttons: [],
        roles: [],
        name: "",
        avatar: ""
      };
    }
  }
});
